package org.gruposp2p.aula.gwt.client.representation;

import static org.gruposp2p.aula.gwt.client.util.XmlLabelConstants.*;

import java.util.ArrayList;
import java.util.List;
import org.gruposp2p.aula.gwt.client.content.GlassedDialog;
import org.gruposp2p.aula.gwt.client.event.AulaEventBus;
import org.gruposp2p.aula.gwt.client.event.CoursegroupChangeEvent;
import org.gruposp2p.aula.gwt.client.event.SubjectChangeEvent;
import org.gruposp2p.aula.gwt.client.model.Coursegroup;
import org.gruposp2p.aula.gwt.client.model.Link;
import org.gruposp2p.aula.gwt.client.model.Subject;
import org.restlet.gwt.Callback;
import org.restlet.gwt.Client;
import org.restlet.gwt.data.MediaType;
import org.restlet.gwt.data.Protocol;
import org.restlet.gwt.data.Request;
import org.restlet.gwt.data.Response;
import org.restlet.gwt.data.Status;
import org.restlet.gwt.resource.XmlRepresentation;
import com.google.gwt.core.client.GWT;
import com.google.gwt.xml.client.Document;
import com.google.gwt.xml.client.Element;
import com.google.gwt.xml.client.NodeList;
import com.google.gwt.xml.client.Text;
import com.google.gwt.xml.client.XMLParser;

public class SubjectRepresentation {
	
	private static SubjectRepresentation instance = new SubjectRepresentation();
	
	/**
	 * Method that reads the Courses representation
	 *<?xml version="1.0" encoding="UTF-8"?>
	 *	<subject>
     *		<description>descripción asignatura 111</description>
     *		<subjectLink name="subject 111" id="111" href="http://localhost:8080/rest/subject/111"/>
     *		<courseLink name="Curso 22" id="1" href="http://localhost:8080/rest/course/1"/>
     *		<coursegroups/>
     *		<itemcalificables>
     *			<itemcalificableLink name="NombreItemcalificable aaa"
     *				id="120" href="http://localhost:8080/rest/itemcalificable/120"/>
     *			</itemcalificables>
     *	<absences>
     *		<absenceLink name="subject 111 - 2009-05-23" id="113" 
     *		href="http://localhost:8080/rest/absence/113"/>
     *	</absences>
	 *</subject>
	 * 
	 */	
	private Subject getSubject (XmlRepresentation xmlRepresentation) {
		Subject subject = new Subject ();
		final Document xmlDoc = xmlRepresentation.getDocument();
		final Element subjectElement = xmlDoc.getDocumentElement();
		XMLParser.removeWhitespace(subjectElement);
		NodeList descriptionNodes = subjectElement.getElementsByTagName(DESCRIPTION_ELEMENT);
		if (descriptionNodes != null) {
			Element descriptionElement = (Element)descriptionNodes.item(0);
			subject.setDescription(descriptionElement.getFirstChild().getNodeValue());
		}	
		Element subjectLinkElement = (Element)subjectElement.getElementsByTagName(SUBJECTLINK_ELEMENT).item(0);
		Link subjectLink = new Link();
		subjectLink.setHref(subjectLinkElement.getAttribute(HREF_ATTRIBUTE));
		subjectLink.setId(subjectLinkElement.getAttribute(ID_ATTRIBUTE));
		subjectLink.setName(subjectLinkElement.getAttribute(NAME_ATTRIBUTE));	
		subject.setLink(subjectLink);		
		Element courseLinkElement = (Element)subjectElement.getElementsByTagName(COURSELINK_ELEMENT).item(0);
		Link courseLink = new Link();
		courseLink.setHref(courseLinkElement.getAttribute(HREF_ATTRIBUTE));
		courseLink.setId(courseLinkElement.getAttribute(ID_ATTRIBUTE));
		courseLink.setName(courseLinkElement.getAttribute(NAME_ATTRIBUTE));	
		subject.setCourseLink(courseLink);
		NodeList itemcalificablesNodes = subjectElement.getElementsByTagName(ITEMCALIFICABLES_ELEMENT);
		if (itemcalificablesNodes != null) {
			List<Link> itemcalificablesLinks = new ArrayList<Link>();
			for (int i= 0; i < itemcalificablesNodes.getLength(); i++) {
				Link itemcalificableLink = new Link();
 	 		    Element itemcalificableElement = (Element)itemcalificablesNodes.item(i);
 	 		    if (itemcalificableElement != null) {
 	 		    	itemcalificableLink.setHref(itemcalificableElement.getAttribute(HREF_ATTRIBUTE));
 	 		    	itemcalificableLink.setId(itemcalificableElement.getAttribute(ID_ATTRIBUTE));
 	 		    	itemcalificableLink.setName(itemcalificableElement.getAttribute(NAME_ATTRIBUTE));
 	 		    	itemcalificablesLinks.add(itemcalificableLink);
 	 		    }				
			}
			subject.setItemcalificablesLinks(itemcalificablesLinks);
		}
		NodeList absencesNodes = subjectElement.getElementsByTagName(ABSENCES_ELEMENT);
		if (absencesNodes != null) {
			List<Link> absencesLinks = new ArrayList<Link>();
			for (int i= 0; i < absencesNodes.getLength(); i++) {
				Link absenceLink = new Link();
 	 		    Element absenceElement = (Element)absencesNodes.item(i);
 	 		    if (absenceElement != null) {
 	 		    	absenceLink.setHref(subjectElement.getAttribute(HREF_ATTRIBUTE));
 	 		    	absenceLink.setId(subjectElement.getAttribute(ID_ATTRIBUTE));
 	 		    	absenceLink.setName(subjectElement.getAttribute(NAME_ATTRIBUTE));
 	 		    	absencesLinks.add(absenceLink);
 	 		    }				
			}
			subject.setAbsencesLinks(absencesLinks);
		}		
		return subject; 
	}
	
	/**
	 * Method that reads the Courses representation
	 * <?xml version="1.0" encoding="UTF-8"?>
	 * <coursegroup>
	 *    <description>descripción grupo 888</description>
	 *    <coursegroupLink name="Nombre grupo 888" id="3" href="http://localhost:8080/rest/coursegroup/3"/>
	 *    <courseLink name="Curso 222" id="1" href="http://localhost:8080/rest/course/1"/>
	 *    <students>
	 *        <studentLink name="name1 mmm" id="101" href="http://localhost:8080/rest/student/101"/>
	 *    </students>
	 * </coursegroup>
	 * 
	 */		
	private XmlRepresentation getRepresentation (Subject subject) {
		XmlRepresentation result = null;
	    Document xmlDoc = XMLParser.createDocument();
	    Element coursegroupElement = xmlDoc.createElement(COURSEGROUP_ELEMENT);
	    Element studentsElement = xmlDoc.createElement(STUDENTS_ELEMENT);
	    List<Link> studentsLinks = subject.getItemcalificablesLinks();
	    if (studentsLinks != null) {
		    for (Link link : studentsLinks) {
		    	Element studentElement = xmlDoc.createElement("studentLink");
		    	studentElement.setAttribute(NAME_ATTRIBUTE, link.getName());
		    	studentElement.setAttribute(ID_ATTRIBUTE, link.getId());
		    	studentElement.setAttribute(HREF_ATTRIBUTE, link.getHref());
		    	studentsElement.appendChild(studentElement);
		    }	    	
	    } 
	    coursegroupElement.appendChild(studentsElement); 
    	Element coursegroupDescriptionElement = xmlDoc.createElement(DESCRIPTION_ELEMENT);
    	Text descriptionTxt = xmlDoc.createTextNode("");
    	coursegroupDescriptionElement.appendChild(descriptionTxt);   	
    	coursegroupElement.appendChild(coursegroupDescriptionElement);
	    result = new XmlRepresentation(MediaType.TEXT_XML, xmlDoc);
	    
	    return result;
	}
	
	public void getSubject (Link subjectLink) {
		GlassedDialog.getInstance().showLoadingCoursesDialog();
		final Client client = new Client(Protocol.HTTP);
		client.get(subjectLink.getHref(), new Callback() {
			@Override
			public void onEvent(Request request, Response response) {
				SubjectChangeEvent subjectChangeEvent = new SubjectChangeEvent();
				Status status = response.getStatus();
				if (status.getCode() == Status.SUCCESS_OK.getCode()) {
					GWT.log("response.getStatus().getName(): " + response.getStatus().getName(), null); 
					subjectChangeEvent.setSubject(getSubject(response.getEntityAsXml()));
					AulaEventBus.getInstance().fireEvent(subjectChangeEvent);	
					GlassedDialog.getInstance().hideDialog();
				} else {
					GlassedDialog.getInstance().showErrorGettingResource(response.getStatus());
				}
			}}); 
	}
	
	public void putSubject (Subject subject) {
		final Client client = new Client(Protocol.HTTP);
		client.put(subject.getLink().getHref(), getRepresentation(subject), new Callback() {
		@Override
		public void onEvent(Request request, Response response) {
			GWT.log("response.getStatus(): " + response.getStatus(), null);
		}});
	}
		
	public static SubjectRepresentation getInstance() {
		return instance;
	}	  

}